package org.gdstash.ui.character;

import org.gdstash.character.GDChar;
import org.gdstash.ui.GDStashFrame;
import org.gdstash.ui.select.IntLenDocFilter;
import org.gdstash.ui.util.AdjustablePanel;
import org.gdstash.util.GDImagePool;
import org.gdstash.util.GDMsgFormatter;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.text.AbstractDocument;
import javax.swing.text.DocumentFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class GDCharAttributePane extends AdjustablePanel {
    private static final int ATTRIB_DIGITS = 6;
    private static final int HEALTH_DIGITS = 8;
    private JLabel lblPhysique;
    private JLabel lblCunning;
    private JLabel lblSpirit;
    private JLabel lblHealth;
    private JLabel lblEnergy;
    private JTextField ftPhysique;
    private JButton btnPhysiquePlus;
    private JButton btnPhysiqueMinus;
    private JTextField ftCunning;
    private JButton btnCunningPlus;
    private JButton btnCunningMinus;
    private JTextField ftSpirit;
    private JButton btnSpiritPlus;
    private JButton btnSpiritMinus;
    private JTextField ftHealth;
    private JTextField ftEnergy;
    private GDCharStatEditPane editPane;

    public GDCharAttributePane(final GDCharStatEditPane editPane) {
        this.editPane = editPane;
        this.adjustUI();
        final JPanel pnlPhysique = this.buildPlusMinusButtonPanel(this.ftPhysique, this.btnPhysiquePlus, this.btnPhysiqueMinus);
        final JPanel pnlCunning = this.buildPlusMinusButtonPanel(this.ftCunning, this.btnCunningPlus, this.btnCunningMinus);
        final JPanel pnlSpirit = this.buildPlusMinusButtonPanel(this.ftSpirit, this.btnSpiritPlus, this.btnSpiritMinus);
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        layout = new GroupLayout(this);
        this.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(this.lblPhysique).addComponent(this.lblCunning).addComponent(this.lblSpirit).addComponent(this.lblHealth).addComponent(this.lblEnergy)).addGroup(layout.createParallelGroup().addComponent(pnlPhysique).addComponent(pnlCunning).addComponent(pnlSpirit).addComponent(this.ftHealth).addComponent(this.ftEnergy));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(this.lblPhysique).addComponent(pnlPhysique)).addGroup(layout.createParallelGroup().addComponent(this.lblCunning).addComponent(pnlCunning)).addGroup(layout.createParallelGroup().addComponent(this.lblSpirit).addComponent(pnlSpirit)).addGroup(layout.createParallelGroup().addComponent(this.lblHealth).addComponent(this.ftHealth)).addGroup(layout.createParallelGroup().addComponent(this.lblEnergy).addComponent(this.ftEnergy));
        layout.setVerticalGroup(vGroup);
        layout.linkSize(0, this.lblPhysique, this.lblCunning);
        layout.linkSize(0, this.lblPhysique, this.lblSpirit);
        layout.linkSize(0, this.lblPhysique, this.lblHealth);
        layout.linkSize(0, this.lblPhysique, this.lblEnergy);
        layout.linkSize(0, pnlPhysique, pnlCunning);
        layout.linkSize(0, pnlPhysique, pnlSpirit);
        layout.linkSize(0, pnlPhysique, this.ftHealth);
        layout.linkSize(0, pnlPhysique, this.ftEnergy);
        layout.linkSize(1, this.lblPhysique, this.lblCunning);
        layout.linkSize(1, this.lblPhysique, this.lblSpirit);
        layout.linkSize(1, this.lblPhysique, this.lblHealth);
        layout.linkSize(1, this.lblPhysique, this.lblEnergy);
        layout.linkSize(1, this.lblPhysique, pnlPhysique);
        layout.linkSize(1, this.lblPhysique, pnlCunning);
        layout.linkSize(1, this.lblPhysique, pnlSpirit);
        layout.linkSize(1, this.lblPhysique, this.ftHealth);
        layout.linkSize(1, this.lblPhysique, this.ftEnergy);
    }

    @Override
    public void adjustUI() {
        Font fntLabel = UIManager.getDefaults().getFont("Label.font");
        Font fntButton = UIManager.getDefaults().getFont("Button.font");
        if (fntButton == null) {
            fntButton = fntLabel;
        }
        Font fntFText = UIManager.getDefaults().getFont("FormattedTextField.font");
        if (fntFText == null) {
            fntFText = fntLabel;
        }
        Font fntBorder = UIManager.getDefaults().getFont("TitledBorder.font");
        if (fntBorder == null) {
            fntBorder = fntLabel;
        }
        fntLabel = fntLabel.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        fntButton = fntButton.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        fntFText = fntFText.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        fntBorder = fntBorder.deriveFont((float) GDStashFrame.iniConfig.sectUI.fontSize);
        final Border lowered = BorderFactory.createEtchedBorder(1);
        final Border raised = BorderFactory.createEtchedBorder(0);
        final Border compound = BorderFactory.createCompoundBorder(raised, lowered);
        final TitledBorder text = BorderFactory.createTitledBorder(compound, GDMsgFormatter.getString(GDMsgFormatter.rbGD, "TXT_CHAR_ATTRIBUTES"));
        text.setTitleFont(fntBorder);
        this.setBorder(text);
        if (this.lblPhysique == null) {
            this.lblPhysique = new JLabel();
        }
        this.lblPhysique.setText(GDMsgFormatter.getString(GDMsgFormatter.rbGD, "TXT_CHAR_STAT_PHYSIQUE"));
        this.lblPhysique.setFont(fntLabel);
        if (this.ftPhysique == null) {
            this.ftPhysique = new JFormattedTextField();
            final DocumentFilter filter = new IntLenDocFilter(6);
            final AbstractDocument doc = (AbstractDocument) this.ftPhysique.getDocument();
            doc.setDocumentFilter(filter);
        }
        this.ftPhysique.setPreferredSize(new Dimension(GDStashFrame.iniConfig.sectUI.fontSize * 5, GDStashFrame.iniConfig.sectUI.fontSize * 2));
        this.ftPhysique.setFont(fntFText);
        if (this.btnPhysiquePlus == null) {
            (this.btnPhysiquePlus = new JButton()).addActionListener(new PlusActionListener(this.ftPhysique));
        }
        this.btnPhysiquePlus.setIcon(GDImagePool.iconPlus16);
        this.btnPhysiquePlus.setFont(fntButton);
        if (this.btnPhysiqueMinus == null) {
            (this.btnPhysiqueMinus = new JButton()).addActionListener(new MinusActionListener(this.ftPhysique));
        }
        this.btnPhysiqueMinus.setIcon(GDImagePool.iconMinus16);
        this.btnPhysiqueMinus.setFont(fntButton);
        if (this.lblCunning == null) {
            this.lblCunning = new JLabel();
        }
        this.lblCunning.setText(GDMsgFormatter.getString(GDMsgFormatter.rbGD, "TXT_CHAR_STAT_CUNNING"));
        this.lblCunning.setFont(fntLabel);
        if (this.ftCunning == null) {
            this.ftCunning = new JFormattedTextField();
            final DocumentFilter filter = new IntLenDocFilter(6);
            final AbstractDocument doc = (AbstractDocument) this.ftCunning.getDocument();
            doc.setDocumentFilter(filter);
        }
        this.ftCunning.setFont(fntFText);
        if (this.btnCunningPlus == null) {
            (this.btnCunningPlus = new JButton()).addActionListener(new PlusActionListener(this.ftCunning));
        }
        this.btnCunningPlus.setIcon(GDImagePool.iconPlus16);
        this.btnCunningPlus.setFont(fntButton);
        if (this.btnCunningMinus == null) {
            (this.btnCunningMinus = new JButton()).addActionListener(new MinusActionListener(this.ftCunning));
        }
        this.btnCunningMinus.setIcon(GDImagePool.iconMinus16);
        this.btnCunningMinus.setFont(fntButton);
        if (this.lblSpirit == null) {
            this.lblSpirit = new JLabel();
        }
        this.lblSpirit.setText(GDMsgFormatter.getString(GDMsgFormatter.rbGD, "TXT_CHAR_STAT_SPIRIT"));
        this.lblSpirit.setFont(fntLabel);
        if (this.ftSpirit == null) {
            this.ftSpirit = new JFormattedTextField();
            final DocumentFilter filter = new IntLenDocFilter(6);
            final AbstractDocument doc = (AbstractDocument) this.ftSpirit.getDocument();
            doc.setDocumentFilter(filter);
        }
        this.ftSpirit.setFont(fntFText);
        if (this.btnSpiritPlus == null) {
            (this.btnSpiritPlus = new JButton()).addActionListener(new PlusActionListener(this.ftSpirit));
        }
        this.btnSpiritPlus.setIcon(GDImagePool.iconPlus16);
        this.btnSpiritPlus.setFont(fntButton);
        if (this.btnSpiritMinus == null) {
            (this.btnSpiritMinus = new JButton()).addActionListener(new MinusActionListener(this.ftSpirit));
        }
        this.btnSpiritMinus.setIcon(GDImagePool.iconMinus16);
        this.btnSpiritMinus.setFont(fntButton);
        if (this.lblHealth == null) {
            this.lblHealth = new JLabel();
        }
        this.lblHealth.setText(GDMsgFormatter.getString(GDMsgFormatter.rbGD, "TXT_CHAR_STAT_HEALTH"));
        this.lblHealth.setFont(fntLabel);
        if (this.ftHealth == null) {
            this.ftHealth = new JFormattedTextField();
            final DocumentFilter filter = new IntLenDocFilter(8);
            final AbstractDocument doc = (AbstractDocument) this.ftHealth.getDocument();
            doc.setDocumentFilter(filter);
            this.ftHealth.setEditable(false);
        }
        this.ftHealth.setFont(fntFText);
        if (this.lblEnergy == null) {
            this.lblEnergy = new JLabel();
        }
        this.lblEnergy.setText(GDMsgFormatter.getString(GDMsgFormatter.rbGD, "TXT_CHAR_STAT_ENERGY"));
        this.lblEnergy.setFont(fntLabel);
        if (this.ftEnergy == null) {
            this.ftEnergy = new JFormattedTextField();
            final DocumentFilter filter = new IntLenDocFilter(8);
            final AbstractDocument doc = (AbstractDocument) this.ftEnergy.getDocument();
            doc.setDocumentFilter(filter);
            this.ftEnergy.setEditable(false);
        }
        this.ftEnergy.setFont(fntFText);
    }

    private JPanel buildPlusMinusButtonPanel(final JTextField textField, final JButton btnPlus, final JButton btnMinus) {
        final JPanel panel = new JPanel();
        GroupLayout layout = null;
        GroupLayout.SequentialGroup hGroup = null;
        GroupLayout.SequentialGroup vGroup = null;
        layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(false);
        layout.setAutoCreateContainerGaps(false);
        hGroup = layout.createSequentialGroup();
        hGroup.addGroup(layout.createParallelGroup().addComponent(btnMinus)).addGroup(layout.createParallelGroup().addComponent(textField)).addGroup(layout.createParallelGroup().addComponent(btnPlus));
        layout.setHorizontalGroup(hGroup);
        vGroup = layout.createSequentialGroup();
        vGroup.addGroup(layout.createParallelGroup().addComponent(btnMinus).addComponent(textField).addComponent(btnPlus));
        layout.setVerticalGroup(vGroup);
        layout.linkSize(0, btnMinus, btnPlus);
        layout.linkSize(1, btnMinus, textField);
        layout.linkSize(1, btnMinus, btnPlus);
        return panel;
    }

    public void setChar(final GDChar gdc) {
        float physique = 0.0f;
        float cunning = 0.0f;
        float spirit = 0.0f;
        float health = 0.0f;
        float energy = 0.0f;
        if (gdc != null) {
            physique = gdc.getPhysique();
            cunning = gdc.getCunning();
            spirit = gdc.getSpirit();
            health = gdc.getHealth();
            energy = gdc.getEnergy();
        }
        this.ftPhysique.setText(Integer.toString((int) physique));
        this.ftCunning.setText(Integer.toString((int) cunning));
        this.ftSpirit.setText(Integer.toString((int) spirit));
        this.ftHealth.setText(Integer.toString((int) health));
        this.ftEnergy.setText(Integer.toString((int) energy));
    }

    public void updateChar(final GDChar gdc) {
        if (gdc == null) {
            return;
        }
        gdc.setPhysique((float) Integer.parseInt(this.ftPhysique.getText()));
        gdc.setCunning((float) Integer.parseInt(this.ftCunning.getText()));
        gdc.setSpirit(Integer.parseInt(this.ftSpirit.getText()));
        gdc.setHealth((float) Integer.parseInt(this.ftHealth.getText()));
        gdc.setEnergy((float) Integer.parseInt(this.ftEnergy.getText()));
    }

    public float getHealth() {
        return Float.parseFloat(this.ftHealth.getText());
    }

    public float getEnergy() {
        return Float.parseFloat(this.ftEnergy.getText());
    }

    public void setHealth(final float health) {
        this.ftHealth.setText(Integer.toString((int) health));
    }

    public void setEnergy(final float energy) {
        this.ftEnergy.setText(Integer.toString((int) energy));
    }

    private class PlusActionListener implements ActionListener {
        private JTextField textField;

        public PlusActionListener(final JTextField textField) {
            this.textField = textField;
        }

        @Override
        public void actionPerformed(final ActionEvent ev) {
            final int val = Integer.parseInt(this.textField.getText());
            final int points = GDCharAttributePane.this.editPane.getStatPoints();
            if (points > 0) {
                if (this.textField == GDCharAttributePane.this.ftCunning) {
                    this.textField.setText(Integer.toString(val + GDStashFrame.enginePlayer.getIncDex()));
                }
                if (this.textField == GDCharAttributePane.this.ftPhysique) {
                    this.textField.setText(Integer.toString(val + GDStashFrame.enginePlayer.getIncStr()));
                    final float health = GDCharAttributePane.this.editPane.getHealth();
                    GDCharAttributePane.this.editPane.setHealth(health + GDStashFrame.enginePlayer.getIncLife());
                }
                if (this.textField == GDCharAttributePane.this.ftSpirit) {
                    this.textField.setText(Integer.toString(val + GDStashFrame.enginePlayer.getIncInt()));
                    final float energy = GDCharAttributePane.this.editPane.getEnergy();
                    GDCharAttributePane.this.editPane.setEnergy(energy + GDStashFrame.enginePlayer.getIncMana());
                }
                GDCharAttributePane.this.editPane.setStatPoints(points - 1);
            }
        }
    }

    private class MinusActionListener implements ActionListener {
        private JTextField textField;

        public MinusActionListener(final JTextField textField) {
            this.textField = textField;
        }

        @Override
        public void actionPerformed(final ActionEvent ev) {
            final int val = Integer.parseInt(this.textField.getText());
            if (this.textField == GDCharAttributePane.this.ftCunning) {
                final int baseStat = GDStashFrame.enginePlayer.getBaseDex();
                final int incStat = GDStashFrame.enginePlayer.getIncDex();
                if (val < baseStat + incStat) {
                    return;
                }
                this.textField.setText(Integer.toString(val - incStat));
            }
            if (this.textField == GDCharAttributePane.this.ftPhysique) {
                final int baseStat = GDStashFrame.enginePlayer.getBaseStr();
                final int incStat = GDStashFrame.enginePlayer.getIncStr();
                if (val < baseStat + incStat) {
                    return;
                }
                final float health = GDCharAttributePane.this.editPane.getHealth();
                final int baseHealth = GDStashFrame.enginePlayer.getBaseLife();
                final int incHealth = GDStashFrame.enginePlayer.getIncLife();
                if (health < baseHealth + incHealth) {
                    return;
                }
                this.textField.setText(Integer.toString(val - incStat));
                GDCharAttributePane.this.editPane.setHealth(health - incHealth);
            }
            if (this.textField == GDCharAttributePane.this.ftSpirit) {
                final int baseStat = GDStashFrame.enginePlayer.getBaseInt();
                final int incStat = GDStashFrame.enginePlayer.getIncInt();
                if (val < baseStat + incStat) {
                    return;
                }
                this.textField.setText(Integer.toString(val - incStat));
                final float energy = GDCharAttributePane.this.editPane.getEnergy();
                final int baseEnergy = GDStashFrame.enginePlayer.getBaseMana();
                final int incEnergy = GDStashFrame.enginePlayer.getIncMana();
                if (energy < baseEnergy + incEnergy) {
                    return;
                }
                this.textField.setText(Integer.toString(val - incStat));
                GDCharAttributePane.this.editPane.setEnergy(energy - incEnergy);
            }
            final int points = GDCharAttributePane.this.editPane.getStatPoints();
            GDCharAttributePane.this.editPane.setStatPoints(points + 1);
        }
    }
}
